package com.markyao.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.markyao.dao.pojo.User;
import com.markyao.service.impl.UserServiceImpl;
import com.markyao.vo.parmas.UserParmas;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class UserUtils {
    static final int goodid=10000017;
    static final String md5mm = "123456Mky!@#$$";
    static final String loginUrl = "http://localhost:80/users/login";//登录url
    static final String miaoshaUrl="http://localhost:80/miaosha/getpath/"+goodid;//秒杀url
    static final String miaoshaMqUrl="http://localhost:80/miaosha/path/seckill?goodsId="+goodid;//进入秒杀消息队列url
    static final String miaoshaResultUrl="http://localhost:80/miaosha/result/"+goodid;//验证秒杀结果url
    static final String txtLocation="Z:/tokens.txt";

    static int count=800;//模拟用户数(线程数)
    private static void createUserToken(int count) throws Exception{
        //生成用户的token存放到txt文件中
        List<User> users = new ArrayList<User>(count);
        //生成用户
        for(int i=0;i<count;i++) {
            User user = new User();
            user.setUid(i+2);
            user.setUsername("user"+i);
            user.setPassword(123456+"");
            users.add(user);
        }
        //登录，生成token
        File file = new File(txtLocation);
        if(file.exists()) {
            file.delete();
        }
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        file.createNewFile();
        raf.seek(0);
        for(int i=0;i<users.size();i++) {
            User user = users.get(i);
            String token = getTokens(user.getUsername(),user.getPassword());
            System.out.println("create token : " + user.getUid());
            String row = user.getUid()+","+token;
            raf.seek(raf.length());
            raf.write(row.getBytes());
            raf.write("\r\n".getBytes());
            System.out.println("write to file : " + user.getUid());
        }
        raf.close();
        System.out.println("over");
    }

    public static String getTokens(String username,String password) throws InterruptedException, IOException {
        //使用httpClient模拟客户端发起请求,先生成token
        HttpPost httpPost = new HttpPost(loginUrl);
        //post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
        JSONObject json = new JSONObject();
        json.put("username",username);
        json.put("password",password);
        StringEntity se = null;
        String token ="";
        CloseableHttpClient httpClient=null;
        CloseableHttpResponse httpResponse=null;
        try {
            se = new StringEntity(json.toString());
            //设置编码格式
            se.setContentEncoding("UTF-8");
            //设置数据类型
            se.setContentType("application/json");
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
            httpPost.setEntity(se);
            httpClient = HttpClientBuilder.create().build();
            httpResponse = httpClient.execute(httpPost);
            HttpEntity entity = httpResponse.getEntity();
            String resData = EntityUtils.toString(entity);
            token = JSONObject.parseObject(resData).getString("data");
        }
        finally {
            httpResponse.close();
            httpClient.close();
            Thread.sleep(500);
        }
        return token;
    }

    public static void run() throws IOException {
        File file = new File(txtLocation);
        FileReader fr = null;
        try {
            fr = new FileReader(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        BufferedReader br = new BufferedReader(fr);
        String line="";
        HashMap<Integer,String>tokenMp=new HashMap<>();
        while(true){
            try {
                if (!((line = br.readLine()) != null)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 一行一行地处理token
            int id= Integer.parseInt(line.split(",")[0]);
            String token=line.split(",")[1];
            tokenMp.put(id,token);
        }
        try {
            br.close();
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        for(int i=2;i<count;i++) {
            //遍历map,取出token发起进攻
            String token = tokenMp.get(i);
            int id=i;
            new Thread(()->{
                try {
                    //通过用户token和id进行模拟秒杀
                    startMiaosha(token,id);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            },"->"+id).start();

        }
    }

    private static void startMiaosha(String token,int id) throws IOException {
        //第一步创建path-----------------------------------------------
        String path = null;
        path=getPath(token,id);
        if (path.length()>0&&!path.equals("")){
            //第二步获取path-->post请求-----------------------------------------------
            boolean flag2 = inQueue(path, token, id);
            if (flag2){
                //第三步验证-----------------------------------------------
                //执行请求获取响应的结果
                boolean flag3 =getResult(token,id);
            }
            else{
                return;
            }
        }
        else{
            return;
        }
    }

    private static String getPath(String token,int id) throws IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response =null;
        HttpGet httpGet = new HttpGet(miaoshaUrl);
        httpGet.setHeader("Authorization", token);//设置好token
        JSONObject jsonObject = null;
        String path="";
        //执行请求获取响应的结果
        try {
            response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            String resData = EntityUtils.toString(entity);
            jsonObject = JSONObject.parseObject(resData);
            path = jsonObject.getString("data");
            System.out.println(id + "-->第一步日志:" + resData);
            if (!jsonObject.getBoolean("success")) {
                System.out.println(id + "-->第一步失败!日志:" + resData);
            }
        } finally {
            response.close();
            client.close();
        }
        return path;
    }

    private static boolean inQueue(String path, String token, int id) throws IOException {
        CloseableHttpResponse httpResponse = null;
        JSONObject jsonObject=null;
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        try {
            String amiaoshaMqUrl = miaoshaMqUrl.replaceAll("path", path);//带入path
            HttpPost httpPost = new HttpPost(amiaoshaMqUrl);
            httpPost.setHeader("Authorization", token);
            httpResponse = httpClient.execute(httpPost);
            HttpEntity entity = httpResponse.getEntity();
            String resData = EntityUtils.toString(entity);
            jsonObject = JSONObject.parseObject(resData);
            System.out.println(id + "-->第二步日志:" + resData);
            if (!jsonObject.getBoolean("success")) {
                System.out.println(id + "-->第二步失败!日志:" + resData);
                return false;
            }
        } finally {
            httpResponse.close();
            httpClient.close();
        }
        return true;
    }

    private static boolean getResult(String token, int id) throws IOException {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        JSONObject jsonObject=null;
        HttpGet httpGet=null;
        CloseableHttpResponse response=null;
        try {
            httpGet = new HttpGet(miaoshaResultUrl);
            httpGet.setHeader("Authorization", token);//设置好token
            response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            String resData = EntityUtils.toString(entity);
            jsonObject = JSONObject.parseObject(resData);
            System.out.println(id + "-->第三步日志:" + resData);
            if (!jsonObject.getBoolean("success")) {
                System.out.println(id + "-->第三步失败!日志:" + resData);
                return false;
            }
            if (jsonObject.getInteger("code") == 111) {
                System.out.println(id + "秒杀成功!");
                return true;
            }
            System.out.println(id + "-->日志:" + resData);
        } finally {
            httpClient.close();
            response.close();
        }
        return false;
    }



    public static void main(String[] args) throws Exception {
        //先模拟生成token
//        createUserToken(count);
        //模拟通过token发起秒杀
//        startMiaosha();
        run();

    }
}
